Source code for /engineering/webperf/master-v2[j1.2]/Controller.javaOriginal file Controller.java
   1 import java.util.*;
   2 import java.io.*;
   3 
   4 public class Controller extends Thread {
   5 
   6    private static final int	sleepPeriod  = 800;
   7    private static final int	idlePeriod   = 250;
   8    private static final int	stateNEW	 = 0;
   9    private static final int	stateREADY   = 1;
  10    private static final int	stateRUNNING = 2;
  11    private static final int	statePAUSED  = 3;
  12    private static final int	statePENDING = 4;
  13    private static final int	stateSTOPPED = 5;
  14 
  15    private static final int 	slaveDISABLED 	 = 0;
  16    private static final int 	slaveDOWN	 	 = 1;
  17    private static final int 	slaveLOADED  	 = 2;
  18    private static final int 	slaveTARGETED	 = 3;
  19    private static final int   slaveUP		 = 4;
  20    private static final int   slaveBAD		 = 5;
  21 
  22    private static final int   runNOT		 = 0;
  23    private static final int   runRUNNING		 = 1;
  24    private static final int   runDONE 		 = 2;
  25    private static final int   runREPORTED		 = 3;
  26 
  27    private static final int   sessionNameDivisor	= 100000;
  28    private static final int   pingPeriod			= 9000;
  29    private static final String  empty	= "...";
  30 
  31    MasterUI		myUI;
  32 
  33    MEventQueue	myEvents;
  34 
  35    HTTPPush		slaves[];
  36    MCommandQueue  slaveQueues[];
  37    int		slaveStates[];
  38    int		runStatus[];
  39 
  40    String		sessionNameTag;
  41 
  42    SessionLog	log;
  43    long		lastPing;
  44 
  45    int		state	= stateNEW;
  46 
  47    MEvent		currentEvent;
  48 
  49    public Controller(MasterUI ui) {
  50       myUI = ui;
  51 	this.initialize();
  52    }
  53 
  54    protected void initialize() {
  55 
  56 	int   index;
  57 
  58 	myEvents 	  = new MEventQueue();
  59 	myUI.register(myEvents);
  60 
  61 	slaves      = new HTTPPush[MasterUI.numberOfSlaves];
  62 	slaveQueues = new MCommandQueue[MasterUI.numberOfSlaves];
  63 	slaveStates = new int[MasterUI.numberOfSlaves];
  64 	runStatus   = new int[MasterUI.numberOfSlaves];
  65 
  66 	for (index = 0; index < MasterUI.numberOfSlaves; index++) {
  67 
  68 	   log = new SessionLog();
  69 
  70 	   slaves[index] 	      = new HTTPPush();
  71 	   slaveQueues[index]   = new MCommandQueue();
  72 
  73 	   slaveStates[index]	= slaveDOWN;
  74 
  75 	   slaves[index].init(slaveQueues[index], log, myEvents, index);
  76 	   slaves[index].start();	
  77 	}
  78    }
  79 
  80    public void run() {
  81 
  82 	MEvent 	tempEvent;
  83       int         index;
  84 	MCommand	aCommand;
  85 
  86 	myUI.putScreenLog("Controller UP!");
  87 	setNew();
  88 
  89 	while(true) { 
  90 
  91 	   // Check for events
  92 	   if (myEvents.has() == true) {
  93 
  94 		currentEvent = myEvents.get();
  95 		switch(currentEvent.event) {
  96 
  97 		   case MEvent.eventUI_STOP:
  98 			handleStop();
  99 			break;
 100 
 101 		   case MEvent.eventUI_START:
 102 			handleStart();
 103 			break;
 104 
 105 		   case MEvent.eventUI_REFRESH:
 106 			handleRefresh();
 107 			break;
 108 
 109 		   case MEvent.eventUI_PAUSE:
 110 			handlePause();
 111 			break;
 112 
 113 		   case MEvent.eventSLAVE_RESPONSE:
 114 			handleSlave();
 115 			break;
 116 
 117 		   case MEvent.eventTIME:
 118 			// nothin now
 119 			break;
 120 		
 121 		   case MEvent.eventNULL:
 122 		   default:
 123 			System.out.println("Software Detected Fault: Controller.run : Unknown event.");
 124 			break;
 125 		}
 126 
 127 	   } else {
 128 
 129 		// any run stuff?
 130 		if (state == stateRUNNING) {
 131 
 132 		   // Do run stuff.  idle breifly at the end.
 133 		   if (checkDone()) {
 134 			
 135 			myUI.putScreenLog("!DONE!  All slaves report done.");
 136 			tempEvent = new MEvent();
 137 			tempEvent.event = MEvent.eventUI_STOP;
 138 			myEvents.put(tempEvent);
 139 		   }
 140 
 141 		   if ( log.getRaw() > (lastPing + pingPeriod)) {
 142 
 143 	  		 for (index = 0; index < MasterUI.numberOfSlaves; index++) {
 144 
 145 	     		    if (runStatus[index] == runRUNNING) {
 146 	 	   		aCommand = new MCommand();
 147 		   		aCommand.command = MCommand.cmdPING;
 148 	 	   		aCommand.item    = empty;
 149 		   		slaveQueues[index].put(aCommand);
 150 			    }
 151 	  		 }
 152 			lastPing = log.getRaw();
 153 		   }
 154 		   
 155 		   try { this.sleep(idlePeriod); } catch (Exception e) { }
 156 
 157 		} else {
 158 		
 159 	 	   // Nuthin' there.  sleep
 160 		   try { this.sleep(sleepPeriod); } catch (Exception e) { }
 161 		}
 162 	   } 
 163 
 164 	} // end while
 165 
 166    }
 167 
 168    private void handleStop() { 
 169 
 170 	MCommand  aCommand;
 171 
 172 	if (state == stateRUNNING) {
 173 	   
 174 	   state = statePENDING;
 175 
 176 	   // Create a session name
 177 	   // send a GO to everyone that is enabled
 178 	   int index;
 179 	   for (index = 0; index < MasterUI.numberOfSlaves; index++) {
 180 
 181 	      if (myUI.isEnabled(index) == true) {
 182 	 	   aCommand = new MCommand();
 183 		   aCommand.command = MCommand.cmdSTOP;
 184 	 	   aCommand.item    = empty;
 185 		   slaveQueues[index].put(aCommand);
 186 		}
 187 
 188 	      if (myUI.isEnabled(index) == true) {
 189 	 	   aCommand = new MCommand();
 190 		   aCommand.command = MCommand.cmdGETLOG;
 191 	 	   aCommand.item    = empty;
 192 		   slaveQueues[index].put(aCommand);
 193 		}
 194 
 195 	   }
 196 
 197 	   myUI.putScreenLog("STOP.  Session name = " + sessionNameTag);
 198    
 199 	} else {
 200 	   myUI.putScreenLog("STOP Rejected.  Not running.");
 201 	}
 202 
 203    }
 204    
 205    private void handleStart() {
 206 
 207 	MCommand	aCommand;
 208 
 209 	// only consider if ready or stopped
 210 	checkReady();
 211 	if ((state == stateREADY)||(state == stateSTOPPED)) {
 212 	   
 213 	   // Create a session name
 214 	   long name = log.getRaw() / sessionNameDivisor;
 215 	   log.startTiming();
 216 	   sessionNameTag = Long.toString(name);
 217 	   
 218 	   // send a GO to everyone that is enabled
 219 	   int index;
 220 	   for (index = 0; index < MasterUI.numberOfSlaves; index++) {
 221 
 222 	      if (myUI.isEnabled(index) == true) {
 223 		   runStatus[index] = runNOT;
 224 
 225 	 	   aCommand = new MCommand();
 226 		   aCommand.command = MCommand.cmdGO;
 227 	 	   aCommand.item    = empty;
 228 		   slaveQueues[index].put(aCommand);
 229 		}
 230 	   }
 231 
 232 	   myUI.putScreenLog("START.  Session name = " + sessionNameTag);
 233    
 234 	} else {
 235 	   myUI.putScreenLog("START Rejected.  Not ready.");
 236 	}
 237    }
 238    
 239    private void handleRefresh() {
 240 
 241 	int	  	index;
 242 	MCommand    aCommand;
 243 
 244 	// If we are running, reject this.
 245 	if ((state == stateRUNNING)||(state == statePAUSED)) {
 246 	   myUI.putScreenLog("REJECTED REFRESH.  Cannot refresh while running.");
 247 	   return;
 248 	}	
 249 
 250 	// Ok.  Queue up targets and loads for all the enabled slaves.
 251 	for (index = 0; index < MasterUI.numberOfSlaves; index++) {
 252 
 253 	   runStatus[index] = runNOT;
 254 
 255 	   if (myUI.isEnabled(index) == true) {
 256 
 257 		aCommand = new MCommand();
 258 		aCommand.command = MCommand.cmdSET_SLAVE_TARGET;
 259 		aCommand.item    = myUI.getTarget(index);
 260 		slaveQueues[index].put(aCommand);
 261 
 262 		// Stop it just in case.
 263 		aCommand 	     = new MCommand();
 264 		aCommand.command = MCommand.cmdSTOP;
 265 		aCommand.item    = myUI.getTarget(index);  //  just so it isnt empty
 266 		slaveQueues[index].put(aCommand);
 267 
 268 		aCommand 	     = new MCommand();
 269 		aCommand.command = MCommand.cmdTARGET;
 270 		aCommand.item    = myUI.getTestMachine();
 271 		slaveQueues[index].put(aCommand);
 272 
 273 		// Read the script.  if it blows up, forget the whole thing
 274 		try { 
 275 		   FileReader in = new FileReader(myUI.getScript(index)); 
 276 		   int 		n;
 277 		   int		size;
 278 		   char[] 		b = new char[1024];
 279 		   StringBuffer	buffer = new StringBuffer();
 280 		   while (true) {
 281 			size     = in.read(b, 0, 1024); 
 282 			if (size == -1) break; 
 283 			buffer.append(b, 0, size); 
 284 		   }
 285 		   in.close();
 286 
 287 		   aCommand 	  = new MCommand();
 288 		   aCommand.command = MCommand.cmdNEW;
 289 		   aCommand.value   = myUI.getUser(index);
 290 	 	   aCommand.item    = buffer.toString();
 291 		   slaveQueues[index].put(aCommand);
 292 
 293 		   setSlaveDown(index);
 294   
 295 		} catch (FileNotFoundException e) {  
 296 			myUI.putScreenLog("ERROR! Script file not found for slave " + index);
 297 			setSlaveBad(index);
 298 		} catch (IOException e) { 
 299 			myUI.putScreenLog("ERROR! Error reading script file for slave " + index);
 300 			setSlaveBad(index);
 301 		}
 302 		
 303 	   } else {
 304 		slaveStates[index] = slaveDISABLED;
 305 
 306 	   } // end if
 307 
 308 	} // end while   
 309 
 310 	// Ok.  now we have to wait.
 311 	setNew();
 312    }
 313 
 314    private void handlePause() {
 315 
 316    } 
 317    
 318    private void handleSlave() {
 319 
 320 	int 	id = currentEvent.id;
 321 
 322 	// Ignore any responses on a bad slave
 323 	if (slaveStates[id] == slaveBAD) return;
 324 
 325 	// Act according to the original command
 326 	switch(currentEvent.index) {
 327 
 328 	   case MCommand.cmdNEW:
 329 		if (currentEvent.value == MEvent.rSUCCESS) {
 330 		   if (slaveStates[id] == slaveTARGETED) {
 331 			setSlaveUp(id);
 332 			checkReady();		
 333 		   } else if (slaveStates[id] == slaveDOWN) {
 334 			slaveStates[id] = slaveLOADED;
 335 		   } else {
 336 			System.out.println("Software Detected Fault: Controller.handleSlave : Odd state for slave when processing NEW response.");
 337 		   }
 338 
 339 		} else {
 340 		   myUI.putScreenLog("!SLAVE ERROR!  Couldn't load script on slave " + id);
 341 		   myUI.putScreenLog("---> " + (String)currentEvent.item);
 342 		   setSlaveBad(id);		
 343 		}
 344 		break;
 345 
 346 	   case MCommand.cmdTARGET:
 347 		if (currentEvent.value == MEvent.rSUCCESS) {
 348 		   if (slaveStates[id] == slaveLOADED) {
 349 			setSlaveUp(id);
 350 			checkReady();		
 351 		   } else if (slaveStates[id] == slaveDOWN) {
 352 			slaveStates[id] = slaveTARGETED;
 353 		   } else {
 354 			System.out.println("Software Detected Fault: Controller.handleSlave : Odd state for slave when processing TARGET response.");
 355 		   }
 356 
 357 		} else {
 358 		   myUI.putScreenLog("!SLAVE ERROR!  Couldn't set target on slave " + id);
 359 		   myUI.putScreenLog("---> " + (String)currentEvent.item);
 360 		   setSlaveBad(id);		
 361 		}
 362 		break;
 363 
 364 	   case MCommand.cmdSET_SLAVE_TARGET:
 365 		// dont do a thing
 366 		break;
 367 
 368 	   case MCommand.cmdSTOP:
 369 		if (currentEvent.value == MEvent.rSUCCESS) {
 370 		   myUI.putScreenLog("STOP.  Slave " + id);
 371 		} else {
 372 		   // Only get pissy if it running
 373 		   if ((state == stateRUNNING)||(state == statePAUSED)) {
 374 		      myUI.putScreenLog("!SLAVE ERROR!  Cound not STOP slave " +id);
 375 		      myUI.putScreenLog("---> " + (String)currentEvent.item);
 376 		      setSlaveBad(id);
 377 		   }		
 378 		}
 379 		break;
 380 
 381 	   case MCommand.cmdPAUSE:
 382 		if (currentEvent.value == MEvent.rSUCCESS) {
 383 		   myUI.putScreenLog("PAUSED.  Slave " + id);
 384 		} else {
 385 		   myUI.putScreenLog("!SLAVE ERROR!  Cound not PAUSE slave " +id);
 386 		   myUI.putScreenLog("---> " + (String)currentEvent.item);
 387 		   setSlaveBad(id);		
 388 		}
 389 		break;
 390 
 391 	   case MCommand.cmdGETLOG:
 392 		if (currentEvent.value == MEvent.rSUCCESS) {
 393 		
 394 		   // Write the logfile
 395 		   try { 
 396 		      FileWriter out = new FileWriter("log-" + sessionNameTag + "-" + currentEvent.id + ".txt"); 
 397 			String     ts  = (String)currentEvent.item;
 398 			out.write(ts, 0, ts.length());
 399 			out.close();
 400 		   } catch (Exception e) {  
 401 		      myUI.putScreenLog("GETLOG - Error writting logfile for " + "log-" + sessionNameTag + "-" + currentEvent.id + ".txt");
 402 		   }
 403 		   myUI.putScreenLog("GETLOG Successful.  Slave " + id);
 404 	  	   runStatus[id] = runREPORTED;
 405 
 406 		} else {
 407 		   myUI.putScreenLog("!SLAVE ERROR!  Cound not GO slave " +id);
 408 		   myUI.putScreenLog("---> " + (String)currentEvent.item);
 409 		   setSlaveBad(id);		
 410 		}
 411 		checkReported();
 412 		break;
 413 
 414 	   case MCommand.cmdGO:
 415 		if (currentEvent.value == MEvent.rSUCCESS) {
 416 		   myUI.putScreenLog("GO Successful.  Slave " + id);
 417 	  	   runStatus[id] = runRUNNING;
 418 		   myUI.setSlaveStatus("RUN", MasterUI.statusGreen, id);
 419 		   checkRunning();
 420 		} else {
 421 		   myUI.putScreenLog("!SLAVE ERROR!  Cound not GO slave " +id);
 422 		   myUI.putScreenLog("---> " + (String)currentEvent.item);
 423 		   setSlaveBad(id);		
 424 		}
 425 		break;
 426 
 427 	   case MCommand.cmdPING:
 428 		if (currentEvent.value == MEvent.rSUCCESS) {
 429 		   // SNARF the status
 430 		   String   text = (String)currentEvent.item;
 431 		   int pingStatus  = text.indexOf('4');  // is it done?
 432 		   if (pingStatus != -1) {
 433 		      runStatus[id] = runDONE;
 434 		   }
 435 			
 436 		} else {
 437 		   myUI.putScreenLog("!SLAVE ERROR!  Failed PING for " +id);
 438 		   setSlaveBad(id);		
 439 		}
 440 		break;
 441 
 442 	   case MCommand.cmdNULL:
 443 	   default:
 444 		System.out.println("Software Detected Fault: Controller.handleSlave : Unknown command.");
 445 		break;
 446 	} // end case
 447 
 448    }
 449 
 450    private void setNew() {
 451 	state = stateNEW;
 452 	myUI.setStatus("NEW", MasterUI.statusGray); 
 453    }
 454 
 455    private void setReady() {
 456 	state = stateREADY;
 457 	myUI.setStatus("READY!", MasterUI.statusGreen); 
 458    }
 459 
 460    private void setRunning() {
 461 	state = stateRUNNING;
 462 	myUI.setStatus("RUNNING!", MasterUI.statusGreen);
 463 	lastPing = log.getRaw();
 464    }
 465 
 466    private void setStopped() {
 467 	state = stateSTOPPED;
 468 	myUI.setStatus("STOPPED", MasterUI.statusGray); 
 469    }
 470 
 471    private void setSlaveDown(int  slot) {
 472 	slaveStates[slot]  = slaveDOWN;
 473 	myUI.setSlaveStatus("DOWN", MasterUI.statusOrange, slot);
 474    }
 475 
 476    private void setSlaveBad(int  slot) {
 477 	slaveStates[slot]  = slaveBAD;
 478 	myUI.setSlaveStatus("BAD", MasterUI.statusRed, slot);
 479    }
 480 
 481    private void setSlaveUp(int  slot) {
 482 	slaveStates[slot] = slaveUP;
 483 	myUI.setSlaveStatus("UP", MasterUI.statusGreen, slot);
 484    }
 485 
 486    private void checkReady() {
 487 
 488 	boolean ready = true;
 489 	int	  index;
 490 
 491 	for (index = 0; index < MasterUI.numberOfSlaves; index++) {
 492 
 493 	   if ((slaveStates[index] != slaveUP)&&
 494 		 (slaveStates[index] != slaveDISABLED)) ready = false;
 495 	}
 496 	if (ready == true) setReady();
 497    }
 498 
 499    private boolean checkDone() {
 500 
 501 	boolean done = true;
 502 	int	  index;
 503 
 504 	for (index = 0; index < MasterUI.numberOfSlaves; index++) {
 505 	   if (runStatus[index] == runRUNNING) done = false;
 506 	}
 507 	return done;
 508    }
 509 
 510    private void checkRunning() {
 511 
 512 	boolean run = true;
 513 	int	  index;
 514 
 515 	for (index = 0; index < MasterUI.numberOfSlaves; index++) {
 516 
 517 	   if ((runStatus[index] !=  runRUNNING)&&
 518 		 (slaveStates[index] != slaveDISABLED)&&
 519 		 (slaveStates[index] != slaveBAD)) run = false;
 520 	}
 521 	if (run == true) setRunning();
 522    }
 523 
 524    private void checkReported() {
 525 
 526 	boolean report = true;
 527 	int	  index;
 528 
 529 	for (index = 0; index < MasterUI.numberOfSlaves; index++) {
 530 
 531 	   if ((runStatus[index] !=  runREPORTED)&&
 532 		 (slaveStates[index] != slaveDISABLED)&&
 533 		 (slaveStates[index] != slaveBAD)) report = false;
 534 	}
 535 	if (report == true) setStopped();
 536    }
 537 
 538 
 539 }